package com.workflow.server.service;

import com.workflow.server.dto.json.ChildNode;
import com.workflow.server.exception.ProcessValidationException;
import org.camunda.bpm.model.bpmn.instance.FlowNode;
import org.camunda.bpm.model.bpmn.instance.Process;

import java.util.Map;

/**
 * <p>title:Camunda流程定义节点创建解析器的父类接口</p>
 *  @author ForeverKobe
 */
public interface IFlowNodeCreateHandler {
    static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(IFlowNodeCreateHandler.class);
    /**
     * <p>在流程中创建一个新的节点，并将其与父节点关联</p>
     * <p>此方法主要用于在给定的父节点下创建一个新的子节点，并更新相关映射以保持数据一致性</p>
     *
     * @param parentNodeId 父节点的唯一标识符，用于建立新节点与父节点的关联
     * @param childNode 要创建的子节点实例，包含子节点的相关信息
     * @param process 当前的流程实例，表示子节点所属的流程上下文
     * @param childNodeMap 子节点的映射表，用于快速查找和管理子节点
     * @return 返回新创建的流程节点实例
     */
    default FlowNode createNode(String parentNodeId, ChildNode childNode, Process process, Map<String, ChildNode> childNodeMap){
        checkNodeType(childNode);
        return doCreateNode(parentNodeId, childNode, process, childNodeMap);
    }

    /**
     * <p>创建节点的具体实现方法</p>
     * <p>该方法需要根据具体的节点类型和流程上下文进行实际的节点创建操作</p>
     *
     * @param parentNodeId 父节点的唯一标识符，用于建立新节点与父节点的关联
     * @param childNode 要创建的子节点实例，包含子节点的相关信息
     * @param process 当前的流程实例，表示子节点所属的流程上下文
     * @param childNodeMap 子节点的映射表，用于快速查找和管理子节点
     * @return返回新创建的流程节点实例
     *
     */
    FlowNode doCreateNode(String parentNodeId, ChildNode childNode, Process process, Map<String, ChildNode> childNodeMap);

    /**
     * <p>获取该节点处理器适用的节点类型</p>
     * <p>具体含义依赖于上下文和实现</p>
     *
     * @return 类型信息的字符串表示
     */
    String getType();



    default void checkNodeType(ChildNode childNode){
        log.info("节点类型为:[{}]", childNode.getType());


        if(!getType().equals(childNode.getType())) {
            throw new ProcessValidationException("节点类型不匹配");
        }
    }

}
